/*
 *  Copyright 2008 Danny Lagrouw
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 */
package org.bastion.example.domain;

import org.bastion.domain.Domain;
import org.bastion.domain.ExampleDomainObject;
import org.bastion.domain.Alert.Level;
import org.bastion.message.AlertMessage;
import org.bastion.message.QueryMessage;
import org.bastion.query.DomainQuery;
import org.bastion.query.Matcher;

/**
 * @author Danny Lagrouw
 * 
 */
public class Reservation extends ExampleDomainObject {

	private static final long serialVersionUID = 1L;

	private Period period;

	private Client client;

	private Vehicle vehicle;

	private Reservation() {
		super(false);
	}
	
	protected Reservation(Period period, Client client, Vehicle vehicle) {
		super();
		this.period = period;
		setClient(client);
		setVehicle(vehicle);
	}

	public static Reservation create(Period period, Client client, Vehicle vehicle) {
		if (vehicle.isAvailable(period)) {
			return new Reservation(period, client, vehicle);
		} else {
			Domain.notify(new AlertMessage("Vehicle not available", Level.ERROR));
			return null;
		}
	}

	private void setVehicle(Vehicle vehicle) {
		this.vehicle = vehicle;
		vehicle.addReservation(this);
	}

	private void setClient(Client client) {
		this.client = client;
		client.addReservation(this);
	}

	public Period getPeriod() {
		return period;
	}

	public Client getClient() {
		return client;
	}

	public Vehicle getVehicle() {
		return vehicle;
	}

	@Override
	public String toString() {
		return super.toString() + "/vehicle=" + vehicle.getRegistration() + "/" + vehicle.getVehicleType().getDescription() + "/client=" + client.getId() + "/" + client.getName() + "/period=" + period;
	}

	public static boolean foundInPeriod(Vehicle vehicle, final Period period) {
		DomainQuery<Reservation> query = new DomainQuery<Reservation>(Reservation.class);
		query.setName("ReservationFoundInPeriod");
		query.setParameter("vehicle", vehicle);
		query.setParameter("startDate", period.getStartDate());
		query.setParameter("endDate", period.getEndDate());
		query.setMatcher(new Matcher<Reservation>() {
			public boolean match(Reservation reservation) {
				return reservation.getPeriod().overlaps(period);
			}
		});
		QueryMessage<Reservation> message = Domain.notify(new QueryMessage<Reservation>(query));
		return message.getSingleResult() != null;
	}

}
